<template>
    <div class="seal-generator">
        <h2>印章生成器</h2>
        <div class="controls">
            <div class="control-section">
                <h3>文字设置</h3>
                <div class="control-group">
                    <label>上弧文字</label>
                    <input v-model="topText" placeholder="请输入上弧文字"/>
                </div>
                <div class="control-group">
                    <label>下弧文字</label>
                    <input v-model="bottomText" placeholder="请输入下弧文字"/>
                </div>
                <div class="control-group">
                    <label>上文字大小</label>
                    <input type="range" min="10" max="100" v-model.number="topFontSize"/>
                    <span>{{ topFontSize }}</span>
                </div>
                <div class="control-group">
                    <label>上文字间距</label>
                    <input type="range" min="0" max="20" v-model.number="topLetterSpacing"/>
                    <span>{{ topLetterSpacing }}</span>
                </div>
                <div class="control-group">
                    <label>上文字偏移</label>
                    <input type="range" min="0" max="100" v-model.number="topOffset"/>
                    <span>{{ topOffset }}</span>
                </div>
                <div class="control-group">
                    <label>上文字拉伸</label>
                    <input type="range" min="0.5" max="2" step="0.05" v-model.number="topScaleX"/>
                    <span>{{ topScaleX }}</span>
                </div>
                <div class="control-group">
                    <label>上文字粗细</label>
                    <input type="range" min="100" max="900" step="100" v-model.number="topFontWeight"/>
                    <span>{{ topFontWeight }}</span>
                </div>
                <div class="control-group">
                    <label>上文字字体</label>
                    <select v-model="topFontFamily">
                        <option v-for="f in fontFamilies" :key="f" :value="f">{{ f }}</option>
                    </select>
                </div>

                <div class="control-group">
                    <label>下文字大小</label>
                    <input type="range" min="8" max="50" v-model.number="bottomFontSize"/>
                    <span>{{ bottomFontSize }}</span>
                </div>
                <div class="control-group">
                    <label>下文字间距</label>
                    <input type="range" min="0" max="20" v-model.number="bottomLetterSpacing"/>
                    <span>{{ bottomLetterSpacing }}</span>
                </div>
                <div class="control-group">
                    <label>下文字偏移</label>
                    <input type="range" min="0" max="100" v-model.number="bottomOffset"/>
                    <span>{{ bottomOffset }}</span>
                </div>
                <div class="control-group">
                    <label>下文字拉伸</label>
                    <input type="range" min="0.5" max="2" step="0.05" v-model.number="bottomScaleX"/>
                    <span>{{ bottomScaleX }}</span>
                </div>
                <div class="control-group">
                    <label>下文字粗细</label>
                    <input type="range" min="100" max="900" step="100" v-model.number="bottomFontWeight"/>
                    <span>{{ bottomFontWeight }}</span>
                </div>
                <div class="control-group">
                    <label>下文字字体</label>
                    <select v-model="bottomFontFamily">
                        <option v-for="f in fontFamilies" :key="f" :value="f">{{ f }}</option>
                    </select>
                </div>
            </div>

            <div class="control-section">
                <h3>印章元素</h3>
                <div class="control-group">
                    <label>圆圈粗细</label>
                    <input type="range" min="1" max="20" v-model.number="circleStrokeWidth"/>
                    <span>{{ circleStrokeWidth }}</span>
                </div>

                <div class="control-group">
                    <label>五角星比例</label>
                    <input type="range" min="0.1" max="0.5" step="0.01" v-model.number="starScale"/>
                    <span>{{ starScale }}</span>
                </div>

                <div class="control-group">
                    <label>破损度</label>
                    <input type="range" min="0" max="0.2" step="0.01" v-model.number="damageLevel"/>
                    <span>{{ damageLevel }}</span>
                </div>

                <div class="control-actions">
                    <button @click="generateHighRes">生成高清图</button>
                    <button @click="resetSettings">重置设置</button>
                </div>
            </div>
        </div>

        <div class="canvas-wrapper">
            <canvas
                    ref="sealCanvas"
                    width="400"
                    height="400"
                    @mousedown="startDrag"
                    @mousemove="drag"
                    @mouseup="endDrag"
                    @mouseleave="endDrag"
            ></canvas>
            <p class="drag-tip">拖拽印章调整位置</p>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            topText: "宇宙超级无敌印章",
            bottomText: "123456789",
            topFontSize: 65,
            bottomFontSize: 21,
            topFontWeight: 700,
            bottomFontWeight: 400,
            topLetterSpacing: 3,
            bottomLetterSpacing: 6,
            topOffset: 61,
            bottomOffset: 14,
            topScaleX: 0.6,
            bottomScaleX: 0.8,
            circleStrokeWidth: 6,
            starScale: 0.3,
            damageLevel: 0.01,
            offsetX: 0,
            offsetY: 0,
            dragStart: null,
            topFontFamily: "SimSun",
            bottomFontFamily: "SimSun",
            fontFamilies: ["SimSun", "SimHei", "KaiTi", "Microsoft YaHei", "FangSong"]
        };
    },
    watch: {
        topText: "drawSeal",
        bottomText: "drawSeal",
        topFontSize: "drawSeal",
        bottomFontSize: "drawSeal",
        topFontWeight: "drawSeal",
        bottomFontWeight: "drawSeal",
        topLetterSpacing: "drawSeal",
        bottomLetterSpacing: "drawSeal",
        topOffset: "drawSeal",
        bottomOffset: "drawSeal",
        topScaleX: "drawSeal",
        bottomScaleX: "drawSeal",
        circleStrokeWidth: "drawSeal",
        starScale: "drawSeal",
        damageLevel: "drawSeal",
        offsetX: "drawSeal",
        offsetY: "drawSeal"
    },
    mounted() {
        this.drawSeal();
    },
    methods: {
        drawSeal() {
            const canvas = this.$refs.sealCanvas;
            const ctx = canvas.getContext("2d");
            const size = canvas.width;
            ctx.clearRect(0, 0, size, size);

            const centerX = size / 2 + this.offsetX;
            const centerY = size / 2 + this.offsetY;
            const radius = size / 2 - 10;

            // 圆圈
            ctx.save();
            ctx.strokeStyle = "red";
            ctx.lineWidth = this.circleStrokeWidth;
            ctx.shadowColor = "rgba(255,0,0,0.4)";
            ctx.shadowBlur = 8;
            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
            ctx.stroke();
            ctx.restore();

            // 五角星
            this.drawStar(ctx, centerX, centerY, radius * this.starScale);

            this.drawArcText(
                ctx, this.topText,
                centerX, centerY, radius - this.topOffset,
                true, this.topFontSize, this.topLetterSpacing, this.topScaleX,
                this.topFontWeight, this.topFontFamily
            );

// 下弧文字
            this.drawArcText(
                ctx, this.bottomText,
                centerX, centerY, radius - this.bottomOffset,
                false, this.bottomFontSize, this.bottomLetterSpacing, this.bottomScaleX,
                this.bottomFontWeight, this.bottomFontFamily
            );
            // 破损
            this.applyDamage(ctx, size, this.damageLevel);
        },
        drawStar(ctx, cx, cy, r) {
            ctx.save();
            ctx.fillStyle = "red";
            ctx.shadowColor = "rgba(255,0,0,0.3)";
            ctx.shadowBlur = 5;
            ctx.beginPath();
            const angle = Math.PI / 5 * 4;
            ctx.moveTo(cx, cy - r);
            for (let i = 1; i < 10; i++) {
                const theta = -Math.PI / 2 + angle * i;
                ctx.lineTo(cx + r * Math.cos(theta), cy + r * Math.sin(theta));
            }
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        },
        drawArcText(ctx, text, cx, cy, r, isTop, fontSize, letterSpacing, scaleX, fontWeight = 400, fontFamily = "SimSun") {
            ctx.save();
            ctx.fillStyle = "red";
            ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}, sans-serif`;
            const charWidths = Array.from(text).map(ch => ctx.measureText(ch).width * scaleX + letterSpacing);
            const totalWidth = charWidths.reduce((a, b) => a + b, 0);
            const anglePerPixel = 1 / r;
            const textAngle = totalWidth * anglePerPixel;
            let startAngle = isTop ? Math.PI / 2 + textAngle / 2 : 3 * Math.PI / 2 - textAngle / 2;

            for (let i = 0; i < text.length; i++) {
                const ch = text[i];
                const w = charWidths[i];
                const theta = w * anglePerPixel;
                const angle = isTop ? startAngle - theta / 2 : startAngle + theta / 2;
                const x = cx + r * Math.cos(angle);
                const y = cy - r * Math.sin(angle);

                ctx.save();
                ctx.translate(x, y);
                ctx.rotate(isTop ? Math.PI / 2 - angle : 3 * Math.PI / 2 - angle);
                ctx.scale(scaleX, 1);
                ctx.fillText(ch, -w / (2 * scaleX), 0);
                ctx.restore();

                startAngle = isTop ? startAngle - theta : startAngle + theta;
            }
            ctx.restore();
        },
        applyDamage(ctx, size, level) {
            if (level <= 0) return;
            const pixels = size * size * level * 0.02;
            for (let i = 0; i < pixels; i++) {
                const x = Math.random() * size;
                const y = Math.random() * size;
                const radius = Math.random() * 5 + 1;
                ctx.clearRect(x - radius / 2, y - radius / 2, radius, radius);
            }
        },
        startDrag(e) {
            this.dragStart = {x: e.offsetX, y: e.offsetY};
        },
        drag(e) {
            if (!this.dragStart) return;
            const dx = e.offsetX - this.dragStart.x;
            const dy = e.offsetY - this.dragStart.y;
            this.offsetX += dx;
            this.offsetY += dy;
            this.dragStart = {x: e.offsetX, y: e.offsetY};
        },
        endDrag() {
            this.dragStart = null;
        },
        generateHighRes() {
            const canvas = this.$refs.sealCanvas;
            const a = document.createElement("a");
            a.href = canvas.toDataURL("image/png");
            a.download = "seal.png";
            a.click();
        },
        resetSettings() {
            this.topText = "张凤科技有限公司";
            this.bottomText = "123456789";
            this.topFontSize = 42;
            this.bottomFontSize = 12;
            this.topLetterSpacing = 4;
            this.bottomLetterSpacing = 10;
            this.topOffset = 50;
            this.bottomOffset = 14;
            this.topScaleX = 1.2;
            this.bottomScaleX = 1.0;
            this.circleStrokeWidth = 6;
            this.starScale = 0.33;
            this.damageLevel = 0.03;
            this.offsetX = 0;
            this.offsetY = 0;
        }
    }
};
</script>

<style scoped>
.seal-generator {
    max-width: 1000px;
    margin: 20px auto;
    padding: 20px;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    background: #f7f7f7;
    border-radius: 16px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.15);
}

h2 {
    text-align: center;
    color: #e74c3c;
    margin-bottom: 30px;
    text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
}

.controls {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-bottom: 30px;
}

.control-section {
    background: #fff;
    padding: 20px;
    border-radius: 12px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
    margin-bottom: 20px;
    flex: 1 1 48%;
}

.control-section h3 {
    margin-bottom: 15px;
    color: #c0392b;
}

.control-group {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
}

.control-group label {
    width: 120px;
    font-weight: 500;
    color: #333;
}

.control-group input[type="text"],
.control-group input[type="number"] {
    flex: 1;
    padding: 6px 10px;
    border-radius: 6px;
    border: 1px solid #ddd;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.08);
}

.control-group input[type="range"] {
    flex: 1;
    margin: 0 10px;
}

.control-group span {
    width: 40px;
    text-align: center;
    font-weight: bold;
    color: #e74c3c;
}

.control-actions {
    margin-top: 15px;
    display: flex;
    justify-content: flex-start;
    gap: 10px;
}

.control-actions button {
    padding: 8px 18px;
    border: none;
    border-radius: 8px;
    background: #e74c3c;
    color: #fff;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.control-actions button:hover {
    background: #c0392b;
    transform: translateY(-2px);
}

.canvas-wrapper {
    text-align: center;
    margin-bottom: 50px;
    position: relative;
}

canvas {
    max-width: 100%;
    background: #fff;
    border: 4px solid #eee;
    border-radius: 50%;
    cursor: grab;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.drag-tip {
    color: #999;
    font-size: 12px;
    margin-top: 8px;
}

@media (max-width: 768px) {
    .control-section {
        flex: 1 1 100%;
    }

    .control-group label {
        width: 100px;
    }
}
</style>